﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.Collections.ObjectModel;

namespace MicroLink.SharePointServices.SolutionAdministration
{
    public static class SolutionManager
    {
        #region AddSolution
        /// <summary>
        /// This adds the solution to your SharePoint farm
        /// </summary>
        /// <param name="solutionPath">The path to your local wsp file</param>
        public static void AddSolution(string solutionPath)
        {
            SPSolution solution = SPFarm.Local.Solutions.Add(solutionPath);
        }
        #endregion

        #region DeploySolution
        /// <summary>
        /// This deployes the solution globally or to all web applications
        /// </summary>
        /// <param name="solutionGuid">The solution's Guid.  This is available from the SolutionDataTable.</param>
        public static void DeploySolution(Guid solutionGuid)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];

            //Check if we are using this as a shortcut to deploying to all web applications
            if (solution.ContainsWebApplicationResource)
            {
                Collection<SPWebApplication> collection = new Collection<SPWebApplication>();
                foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications)
                    collection.Add(webApp);
                DeploySolution(solutionGuid, collection);
            }
            else
            {
                solution.Deploy(DateTime.Now, solution.ContainsGlobalAssembly, true);
            }
        }

        /// <summary>
        /// This deployes the solution to the specified web applications
        /// </summary>
        /// <param name="solutionGuid">The solution's Guid.  This is available from the SolutionDataTable.</param>
        /// <param name="collection">A collection of web application names you wish to deploy the solution to.</param>
        public static void DeploySolution(Guid solutionGuid, Collection<string> collection)
        {
            Collection<SPWebApplication> webAppCollection = new Collection<SPWebApplication>();
            foreach(SPWebApplication webApp in SPWebService.ContentService.WebApplications)
            {
                if(collection.Contains(webApp.Name))
                    webAppCollection.Add(webApp);
            }

            DeploySolution(solutionGuid, webAppCollection);
        }

        /// <summary>
        /// Internal helper function.
        /// </summary>
        /// <param name="solutionGuid"></param>
        /// <param name="collection"></param>
        internal static void DeploySolution(Guid solutionGuid, Collection<SPWebApplication> collection)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];

            //Double check just in case this solution really does not get deployed to a web application.
            if (solution.ContainsWebApplicationResource)
            {
                solution.Deploy(DateTime.Now, solution.ContainsGlobalAssembly, collection, true);
            }
            else
            {
                DeploySolution(solutionGuid);
            }
        }
        #endregion

        #region GetSolution
        /// <summary>
        /// This provides the solution's properties.
        /// </summary>
        /// <param name="solutionGuid">The solution's Guid.  This is available from the SolutionDataTable.</param>
        /// <returns></returns>
        public static SolutionProperties GetSolution(Guid solutionGuid)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];
            Collection<string> collection = new Collection<string>();
            try
            {
                foreach (SPWebApplication webApp in solution.DeployedWebApplications)
                    collection.Add(webApp.Name);
            }
            catch
            {
            }

            SolutionProperties solutionProperties = new SolutionProperties(solutionGuid, solution.Deployed, solution.ContainsWebApplicationResource, collection);

            return solutionProperties;
        }
        #endregion

        #region RetractSolution
        /// <summary>
        /// This retracts the globally deployed solution, or retracts a web application solution from ALL the web applications
        /// it is deployed to.
        /// </summary>
        /// <param name="solutionGuid">The solution's Guid.  This is available from the SolutionDataTable.</param>
        public static void RetractSolution(Guid solutionGuid)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];
            if (solution.ContainsWebApplicationResource)
            {
                RetractSolution(solutionGuid, solution.DeployedWebApplications);
            }
            else
            {
                solution.Retract(DateTime.Now);
            }
        }
        
        /// <summary>
        /// This Retracts the solution for a collection of web applications.
        /// </summary>
        /// <param name="solutionGuid">The solution's Guid.  This is available from the SolutionDataTable.</param>
        /// <param name="collection">The names of the web applications you wish to retract the solution from.</param>
        public static void RetractSolution(Guid solutionGuid, Collection<string> collection)
        {
            Collection<SPWebApplication> webAppCollection = new Collection<SPWebApplication>();

            foreach (SPWebApplication webApp in SPWebService.ContentService.WebApplications)
            {
                if (collection.Contains(webApp.Name))
                    webAppCollection.Add(webApp);
            }

            RetractSolution(solutionGuid, webAppCollection);
        }

        /// <summary>
        /// Internal helper function.
        /// </summary>
        /// <param name="solutionGuid"></param>
        /// <param name="collection"></param>
        internal static void RetractSolution(Guid solutionGuid, Collection<SPWebApplication> collection)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];
            if (solution.ContainsWebApplicationResource)
            {
                solution.Retract(DateTime.Now, collection);
            }
            else
            {
                RetractSolution(solutionGuid);
            }
        }
        #endregion

        #region DeleteSolution
        /// <summary>
        /// This function is used to remove a solution from SharePoint
        /// </summary>
        /// <param name="solutionGuid"></param>
        public static void DeleteSolution(Guid solutionGuid)
        {
            SPSolution solution = SPFarm.Local.Solutions[solutionGuid];
            solution.Delete();
        }
        #endregion
    }
}
